package base

/**
 * Created by Darkness1m on 2017/6/4.
 */
//泛型
open class MyClass<T>(t: T){
    var total = t
}

fun main(args: Array<String>) {
    val m = base.MyClass<Int>(1)
    val mm = base.MyClass(1)//类型可以根据参数推断出来,则可以省略类型
}

//TODO 待加强理解
//协变(? extends X)  逆变(? super X)
//对应于   out             in     ==>型变注解
//大概意思是,对于协变类型参数,

abstract class Source<out T>{
    abstract fun nextT(): T
}
fun demo(strs: base.Source<Number>){//大概意思就是入参的类型必须是调用者的子类, ? extends X,这个 ? 是Number 而 X 是这里的Any
    val objects: base.Source<Any> = strs//这样使用没有问题 Number是extends Any的
//    val obj: base.Source<Double> = strs//这样就是不行的
}
abstract class Comparable<in T>{
    abstract operator fun compareTo(other: T): Int
}
fun demo2(x: base.Comparable<Number>){//大概意思就是入参的类型必须是调用者的父类, ? super X,这个 ? 是Number 而 X是这里的Double
    x.compareTo(1.0)//Double是Number的子类
    val y: base.Comparable<Double> = x//这样都是可以的
//    val z: base.Comparable<Any> = base.getX//这样就是不行的
}

//投影.....不是很理解啊..TODO

//函数
fun <T> singleton(item: T): List<T>{
    return asList(item)
}
fun <T> T.singleton(): String {//扩展函数
    return ""
}

//<>内只能指定一个上界
fun <T : base.Comparable<T>> sort(list: List<T>){}//T extends base.Comparable
//指定多个上界
fun <T> cloneWhenGreater(list: List<T>, threshold: T): List<T>
    where T : base.Comparable<T>,
          T : Cloneable {
    return list.filter { it > threshold }
}